/* 
 * File:   MainServer.cpp
 * Author: Bram
 * 
 * Created on January 12, 2013, 10:28 PM
 */

#include "MainServer.h"

#include "Config.h"
#include "Command.h"
#include "ErrorCommand.h"
#include "DirCommand.h"
#include "InfoCommand.h"
#include "Factory.h"
#include "CommandParser.h"

logger dasLog;


//max error = 27, nieuwe errow word dus 28!


MainServer::MainServer() {
    Config::getInstance()->loadDefaults();
}

MainServer::MainServer(const MainServer& orig) {
}

MainServer::~MainServer() {
}

void MainServer::error(const char * errStr){
    cout << "ERROR: " << errStr << "" << endl;
    exit(1);
}

void MainServer::StartServer()
{
    cParser = new CommandParser("SERVER");
    
    HostInfo uHostAddress;
    string localHostName = uHostAddress.getHostName();
    string localHostAddr = uHostAddress.getHostIPAddress();
    cout << "----------------------------------------" << endl;
    cout << "   My local host information:" << endl;
    cout << "         Name:    " << localHostName << endl;
    cout << "         Address: " << localHostAddr << endl;
    cout << "----------------------------------------" << endl;
    
    
    // open socket on the local host
    TcpSocket * dasServah = new TcpSocket(PORTNUM);
    //TcpSocket dasServah(PORTNUM);
    cout << dasServah;
    dasLog << "server configuation: " << endl;
    dasLog << dasServah;

    dasServah->bindSocket();
    cout   << endl << "server finishes binding process... " << endl;
    dasLog << endl << "server finishes binding process... " << endl;

    dasServah->listenToClient();
    cout   << "server is listening to the port ... " << endl;
    dasLog << "server is listening to the port ... " << endl;

    // wait to accept a client connection.  
    // processing is suspended until the client connects
    cout   << "server is waiting for client connecction ... " << endl;
    dasLog << "server is waiting for client connnection ... " << endl;

    dasLog.winClipboardTEMP(string("cccdit is een test bericht!!!!@ Qa"));
    
    // connection dedicated for client communication
    TcpSocket* client;    
    string clientHost;      // client name etc. 
    client = dasServah->acceptClient(clientHost);

    cout   << endl << "==> A client from [" << clientHost << "] is connected!" << endl << endl;
    dasLog << endl << "==> A client from [" << clientHost << "] is connected!" << endl << endl;

    string  clientMessageIn = "";
    
    queue<Command *> commandQueue;
    
    while(1)
    {
        Command * currCommand;
        
        if(commandQueue.empty()){
            // receive from the client
            int numBytes = client->recieveMessage(clientMessageIn);
            if ( numBytes == -99 ) break;
            if(numBytes > 0){
                currCommand = Command::parseInputCommand(clientMessageIn);
            } else {
                currCommand = 0;
            }
        } else {
            currCommand = commandQueue.front();
            commandQueue.pop();
            if(currCommand == 0){ break;} //als we ene NULL in de queue rammen moetie stoppen!
        }
        
            //checkt of het een valide command is
            if(currCommand != 0){
                //currCommand->ExcecuteServerReceiveCommand(dasServah); // eerst moet de server een bericht ontvangen van de client
                //currCommand->ExcecuteServerSendCommand(dasServah); //dan iets terug sturen!
                cParser->ExcecuteReveiveCommand(client, currCommand, commandQueue);
                cParser->ExcecuteSendCommand(client, currCommand, commandQueue);
                currCommand = 0;
                delete currCommand;
        }
    }
    
    delete cParser;
    delete client;
    delete dasServah;
    
}

void MainServer::StopServer()
{
    
}

void MainServer::StartClient()
{
    cParser = new CommandParser("CLIENT");
    
    HostInfo uHostAddress;
    string localHostName = uHostAddress.getHostName();
    string localHostAddr = uHostAddress.getHostIPAddress();
    cout << "----------------------------------------" << endl;
    cout << "   My local host information:" << endl;
    cout << "         Name:    " << localHostName << endl;
    cout << "         Address: " << localHostAddr << endl;
    cout << "----------------------------------------" << endl;
    
    
    // open socket on the local host
    TcpSocket * dasClient = new TcpSocket(PORTNUM);
    cout << dasClient;
    dasLog << "client configuation: " << endl;
    dasLog << dasClient;

    //dasClient.bindSocket();
    //cout   << endl << "server finishes binding process... " << endl;
    //dasLog << endl << "server finishes binding process... " << endl;

    dasClient->setLingerOnOff(true);
    dasClient->setLingerSeconds(10);
    
    cout   << "client is trying to connect ..." << endl;
    dasLog << "client is trying to connect ..." << endl;
    
    //propeert te verbinden
    //while(!dasClient->connectToServer(string("127.0.0.1"),ADDRESS)){
    //while(!dasClient->connectToServer(string("192.168.0.116"),ADDRESS)){
    bool isConnected = false;
    //string input;
    //getline(cin, input);
    while(!dasClient->connectToServer(string("145.102.84.42"),ADDRESS)){
        cout   << "trying...." << endl;
        sleep(1);
    }
    
    cout   << "client is connected" << endl;
    dasLog << "client is connected" << endl;
    
    queue<Command *> commandQueue;
    
    while(1)
    {
        Command * currCommand;
        
        if(commandQueue.empty()){
            char sendmsg[MAX_MSG_LEN+1];
            string strSendmsg;
            memset(sendmsg,0,sizeof(sendmsg));
            cin.getline(sendmsg,MAX_MSG_LEN);
            sendmsg[MAX_MSG_LEN] = '\0';
            strSendmsg = sendmsg;
            cout << "sending: '" << strSendmsg << "'" << endl;
            if(strSendmsg.length() > 3){
                currCommand = cParser->ParseOutputCommand(strSendmsg);
            } else {
                //cout << "no valid command: '" << strSendmsg << "'!" << endl;
                currCommand = 0;
            }
        } else {
            currCommand = commandQueue.front();
            commandQueue.pop();
            if(currCommand == 0){ break;} //als we ene NULL in de queue rammen moetie stoppen!
        }

        
        

            if(currCommand != 0){
                cParser->ExcecuteSendCommand(dasClient, currCommand, commandQueue);
                cParser->ExcecuteReveiveCommand(dasClient, currCommand, commandQueue);
                //currCommand->PrintFullCout();
                //currCommand->ExcecuteClientSendCommand(dasClient); //eerst stuurt de client iets
                //currCommand->ExcecuteClientReceiveCommand(dasClient); // en dan ontvangt de client iets
            } else {
                cout << " * no valid command * " << endl;
            }
            currCommand = 0;
            delete currCommand;
        
    }
        /*
        int numBytes = dasClient.recieveMessage(clientMessageIn);
        if ( numBytes == -99 ) break;
        if(numBytes > 0){
            cout << "received: '" << clientMessageIn << "'" << endl;
        }
         */
    
    
    delete dasClient;
    delete cParser;
}     

void MainServer::StopClient()
{
    vector<string> tmp;
    string path = "c:\\_tmp\\";
    Utility::getInstance()->getFilesInDirIncludingSubdirs(path,tmp, true);
    
    for(int i = 0; i < tmp.size(); i++){
        cout << i << ": " << tmp[i] << endl;
    }
    
    /*
    //cParser->ParseCommand("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?><Command Name=\"DIR\" Type=\"RECEIVE\" ><Parameters><Parameter>C:\\Data\\DIR1</Parameter><Parameter>C:\\Data\\DIR2</Parameter><Parameter>C:\\Data\\DIR3</Parameter><Parameter>C:\\Data\\DIR4</Parameter></Parameters></Command>");
    //cParser->ParseCommand("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?><Command Name=\"DIR\" Type=\"RECEIVE\" ><Parameters><Parameter a=\"a\">C:DataDIR1</Parameter><Parameter>C:DataDIR2</Parameter><Parameter>C:DataDIR3</Parameter><Parameter>C:DataDIR4</Parameter></Parameters></Command>");
    Command * currCommand = cParser->ParseCommand("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?><Command Name=\"DIR\" Sender=\"SERVER\" ><Parameters><Parameter>C:\\Data\\DIR1</Parameter><Parameter>C:\\Data\\DIR2</Parameter><Parameter>C:\\Data\\DIR3</Parameter><Parameter>C:\\Data\\DIR4</Parameter></Parameters></Command>");
    //checkt of het een valide command is
    if(currCommand != NULL){
        cout << "valid command!" << endl;
        string message = currCommand->buildFullCommand();
    }
     
    delete currCommand;
     */
}

